﻿#include <iostream>
#include <sstream>
#include <locale>
#include <exception>
#include <cstdlib>
#include <string>
#include <chrono>

using namespace std;

class BoolName : public numpunct_byname<char>
{
public:
	BoolName() : numpunct_byname<char>(string("ZH_CN"))
	{
	}
protected:
	virtual string do_truename() const
	{
		//return "yes";
		return u8"是"; //zh_cn 使用的编码是UTF-8
	}
	virtual string do_falsename() const
	{
		//return "no";
		return u8"否";
	}

	virtual string do_grouping() const
	{
		const char group[5] = { 4, 0 };// 4个为一组，适合中文的 万 分位阅读
		return group;
	}
};

int wmain()
{
	{
		try
		{
			locale loczh_cn = locale("ZH_CN");
			auto oldloc = locale::global(loczh_cn); //设置控制台显示的字符编码，否则会出现乱码
			string s = std::use_facet<moneypunct<char>>(loczh_cn).curr_symbol();
			cout << "zh_cn true value: " << std::use_facet<numpunct<char>>(loczh_cn).truename() << endl;
			cout << "zh_cn curr_symbol: " << std::use_facet<moneypunct<char>>(loczh_cn).curr_symbol() << endl; //中文 ￥ 
			cout << "zh_cn decimal point: " << std::use_facet<numpunct<char>>(loczh_cn).decimal_point() << endl << endl;

			locale locdeu = locale("deu_deu");
			locale::global(locdeu); //设置控制台显示的字符编码，否则会出现乱码
			cout << "deu_deu true value: " << std::use_facet<numpunct<char>>(locdeu).truename() << endl;
			cout << "deu_deu curr_symbol: " << std::use_facet<moneypunct<char>>(locdeu).curr_symbol() << endl;
			cout << "deu_deu decimal point: " << std::use_facet<numpunct<char>>(locdeu).decimal_point() << endl;
			cout << endl;
			locale::global(oldloc);

			locale locmy(loczh_cn, new BoolName());
			locale::global(loczh_cn);
			cout.imbue(locmy);
			cout.setf(ios::boolalpha);
			cout << "True value: " << true << endl;
			cout << 123456000 << endl; //4个数字一组划分
			cout << fixed << 123456000.00 << endl << endl; //4个数字一组划分


			locale locC("C");//默认编码
			cout.imbue(locC);
			use_facet<num_put<char>>(locC).put(cout, cout, ' ', 1234.5678);
			cout << endl;

			locale locG("deu_deu.1252");
			cout.imbue(locG);
			use_facet<num_put<char>>(locG).put(cout, cout, ' ', 1234.5678);
			cout << endl;

			cout.imbue(locC);

		}
		catch (const std::exception& e) {
			cerr << "Exception: " << e.what() << endl;
			return -1;
		}
	}
	cout << "1------------------------\n" << endl;

	{
		try {
			auto now = chrono::system_clock::now();
			std::time_t t = chrono::system_clock::to_time_t(now);
			tm nowTM{ 0 };
			localtime_s(&nowTM, &t);

			locale locC("C");
			locale::global(locC);
			const time_put<char>& tpC = use_facet<time_put<char>>(locC);
			// use single conversion specifier
			tpC.put(cout, cout, ' ', &nowTM, 'x');
			cout << endl;
			// use format string:
			string format = "%A %x %I%p\n"; // format: weekday date hour
			tpC.put(cout, cout, ' ', &nowTM, format.c_str(), format.c_str() + format.size());
			cout << endl;

			// print local time with German locale:
			locale locCH("zh_cn");
			locale::global(locCH);
			const time_put<char>& tpG = use_facet<time_put<char>>(locCH);
			tpG.put(cout, cout, ' ', &nowTM, 'x');
			cout << endl;
			tpG.put(cout, cout, ' ', &nowTM, format.c_str(), format.c_str() + format.size());
			ostringstream oss;
			tpG.put(oss, oss, ' ', &nowTM, format.c_str(), format.c_str() + format.size());
			cout << oss.str() << endl;

			string inputstr = u8"星期二 17:35\n";
			cout << "Input String: " << inputstr;
			istringstream iss(inputstr);//必须要有回车符号
			//iss.imbue(locCH); //不用设置，默认会使用locale::global
			const time_get<char>& tgG = use_facet<time_get<char>>(locCH);
			struct tm val;
			ios_base::iostate err = ios_base::goodbit;
			string format2 = "%A %H:%M";
			tgG.get(istreambuf_iterator<char>(iss), istreambuf_iterator<char>(),
				iss, err, &val, format2.c_str(), format2.c_str() + format2.size());
			if (err != ios_base::goodbit) 
			{
				cerr << "invalid format2" << endl;
			}
			else
			{
				cout << u8"星期" << val.tm_wday << u8" ,  时间：" << val.tm_hour << ":" << val.tm_min << endl;
			}
		}
		catch (const std::exception& e) {
			cerr << "Exception: " << e.what() << endl;
			return -2;
		}
	}
	cout << "2------------------------\n" << endl;

}